<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 23 Webpack Advanced | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.21 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 23 Webpack Advanced | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 23 Webpack Advanced | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2021-04-19" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="packer-overview.html"/>
<link rel="next" href="conclusion.html"/>
<script src="libs/jquery-3.5.1/jquery.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/htmlwidgets-1.5.3/htmlwidgets.js"></script>
<script src="libs/plotly-binding-4.9.3/plotly.js"></script>
<script src="libs/typedarray-0.1/typedarray.min.js"></script>
<link href="libs/crosstalk-1.1.1/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk-1.1.1/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css-1.57.1/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main-1.57.1/plotly-latest.min.js"></script>
<script src="libs/core-js-2.5.3/shim.min.js"></script>
<script src="libs/react-16.12.0/react.min.js"></script>
<script src="libs/react-16.12.0/react-dom.min.js"></script>
<script src="libs/reactwidget-1.0.0/react-tools.js"></script>
<script src="libs/reactable-binding-0.2.3/reactable.js"></script>
<script src="libs/r2d3-render-0.1.0/r2d3-render.js"></script>
<script src="libs/webcomponents-2.0.0/webcomponents.js"></script>
<script src="libs/r2d3-binding-0.2.5/r2d3.js"></script>
<script src="libs/d3v6-6.2.0/d3.min.js"></script>
<script src="libs/viz-1.8.2/viz.js"></script>
<link href="libs/DiagrammeR-styles-0.2/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding-1.0.6.1/grViz.js"></script>
<link href="libs/datatables-css-0.0.0/datatables-crosstalk.css" rel="stylesheet" />
<script src="libs/datatables-binding-0.17/datatables.js"></script>
<link href="libs/dt-core-1.10.20/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="libs/dt-core-1.10.20/css/jquery.dataTables.extra.css" rel="stylesheet" />
<script src="libs/dt-core-1.10.20/js/jquery.dataTables.min.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-74544116-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-74544116-1');
</script>
<meta property="og:title" content="Chapter 23 Webpack Advanced | JavaScript for R">
<meta property="og:description" content="Book on using JavaScript with R for visualisations, web development, and computations.">
<meta property="og:image" content="https://book.javascript-for-r.com/images/social.png">
<meta property="og:url" content="https://book.javascript-for-r.com/">
<meta name="twitter:card" content="summary_large_image">
<meta property="og:site_name" content="Chapter 23 Webpack Advanced | JavaScript for R">
<meta name="twitter:image:alt" content="Book on using JavaScript with R for visualisations, web development, and computations.">
<meta name="twitter:site" content="@jdatap">


<style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a><ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
</ul></li>
<li class="part"><span><b>I Basics and Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="intro-overview.html"><a href="intro-overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a><ul>
<li class="chapter" data-level="1.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-overview-rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a><ul>
<li class="chapter" data-level="1.2.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="intro-overview.html"><a href="intro-overview.html#intro-shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="intro-overview.html"><a href="intro-overview.html#intro-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a><ul>
<li class="chapter" data-level="1.3.1" data-path="intro-overview.html"><a href="intro-overview.html#intro-reactr-vuer"><i class="fa fa-check"></i><b>1.3.1</b> reactR &amp; vueR</a></li>
<li class="chapter" data-level="1.3.2" data-path="intro-overview.html"><a href="intro-overview.html#intro-r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a><ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-package-dev"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a><ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-create-pkg"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#basics-documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#basics-installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#basics-build-load-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-json"><i class="fa fa-check"></i><b>2.2</b> JSON</a><ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-tabular"><i class="fa fa-check"></i><b>2.2.2</b> Tabular Data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a><ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-chrome-devtools"><i class="fa fa-check"></i><b>2.3.1</b> Developer Tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-var-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable Declaration and Scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document Object Model</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="prerequisites.html"><a href="prerequisites.html#basics-shiny"><i class="fa fa-check"></i><b>2.4</b> Shiny</a><ul>
<li class="chapter" data-level="2.4.1" data-path="prerequisites.html"><a href="prerequisites.html#basics-static-files"><i class="fa fa-check"></i><b>2.4.1</b> Serving Static Files</a></li>
<li class="chapter" data-level="2.4.2" data-path="prerequisites.html"><a href="prerequisites.html#basics-htmltools"><i class="fa fa-check"></i><b>2.4.2</b> Htmltools</a></li>
<li class="chapter" data-level="2.4.3" data-path="prerequisites.html"><a href="prerequisites.html#basics-deps-pro-cons"><i class="fa fa-check"></i><b>2.4.3</b> Serving vs. htmltools</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html"><i class="fa fa-check"></i><b>3</b> Introduction to Widgets</a><ul>
<li class="chapter" data-level="3.1" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-plotly"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-dt"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
<li class="chapter" data-level="3.3" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-crosstalk"><i class="fa fa-check"></i><b>3.3</b> Crosstalk</a></li>
<li class="chapter" data-level="3.4" data-path="widgets-intro-intro.html"><a href="widgets-intro-intro.html#widgets-intro-conclude"><i class="fa fa-check"></i><b>3.4</b> Wrap-up</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="widgets-basics.html"><a href="widgets-basics.html"><i class="fa fa-check"></i><b>4</b> Basics of Building Widgets</a><ul>
<li class="chapter" data-level="4.1" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-study"><i class="fa fa-check"></i><b>4.1</b> Read and Study</a></li>
<li class="chapter" data-level="4.2" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates"><i class="fa fa-check"></i><b>4.2</b> Candidate Libraries</a><ul>
<li class="chapter" data-level="4.2.1" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-plotly"><i class="fa fa-check"></i><b>4.2.1</b> Plotly.js</a></li>
<li class="chapter" data-level="4.2.2" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-highcharts"><i class="fa fa-check"></i><b>4.2.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.2.3" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-candidates-chart.js"><i class="fa fa-check"></i><b>4.2.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.3" data-path="widgets-basics.html"><a href="widgets-basics.html#widgets-basics-inner-workings"><i class="fa fa-check"></i><b>4.3</b> How It Works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="widgets-first.html"><a href="widgets-first.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a><ul>
<li class="chapter" data-level="5.1" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-htmloutput"><i class="fa fa-check"></i><b>5.2</b> The HTML Output</a></li>
<li class="chapter" data-level="5.3" data-path="widgets-first.html"><a href="widgets-first.html#widgets-first-js-files"><i class="fa fa-check"></i><b>5.3</b> JavaScript Files</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="widgets-realistic.html"><a href="widgets-realistic.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a><ul>
<li class="chapter" data-level="6.1" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-deps"><i class="fa fa-check"></i><b>6.1</b> Dependencies</a></li>
<li class="chapter" data-level="6.2" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-implementation"><i class="fa fa-check"></i><b>6.2</b> Implementation</a></li>
<li class="chapter" data-level="6.3" data-path="widgets-realistic.html"><a href="widgets-realistic.html#widgets-realistic-html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="widgets-full.html"><a href="widgets-full.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a><ul>
<li class="chapter" data-level="7.1" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-deps"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-js"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a><ul>
<li class="chapter" data-level="7.4.1" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-js"><i class="fa fa-check"></i><b>7.4.1</b> Using JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-modify"><i class="fa fa-check"></i><b>7.4.2</b> Modify Serialiser</a></li>
<li class="chapter" data-level="7.4.3" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-replace"><i class="fa fa-check"></i><b>7.4.3</b> Replace Serialiser</a></li>
<li class="chapter" data-level="7.4.4" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-modify-data"><i class="fa fa-check"></i><b>7.4.4</b> Modify the Data</a></li>
<li class="chapter" data-level="7.4.5" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-transform-data-conclusion"><i class="fa fa-check"></i><b>7.4.5</b> Pros and Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="widgets-full.html"><a href="widgets-full.html#widgets-full-on-print"><i class="fa fa-check"></i><b>7.5</b> On Print Method</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="widgets-adv.html"><a href="widgets-adv.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a><ul>
<li class="chapter" data-level="8.1" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-shared"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a><ul>
<li class="chapter" data-level="8.1.1" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-prerender"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks and Security</a></li>
<li class="chapter" data-level="8.4" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-js"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-prepend-append"><i class="fa fa-check"></i><b>8.5</b> Prepend and Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="widgets-adv.html"><a href="widgets-adv.html#widgets-adv-performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="linking-widgets.html"><a href="linking-widgets.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a><ul>
<li class="chapter" data-level="9.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk Examples</a></li>
<li class="chapter" data-level="9.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-req"><i class="fa fa-check"></i><b>9.2</b> Crosstalk Requirements</a></li>
<li class="chapter" data-level="9.3" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-inner-workings"><i class="fa fa-check"></i><b>9.3</b> How it Works</a><ul>
<li class="chapter" data-level="9.3.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-keys"><i class="fa fa-check"></i><b>9.3.1</b> Keys</a></li>
<li class="chapter" data-level="9.3.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-communication-lines"><i class="fa fa-check"></i><b>9.3.2</b> Communication Lines</a></li>
<li class="chapter" data-level="9.3.3" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-groups"><i class="fa fa-check"></i><b>9.3.3</b> Groups</a></li>
</ul></li>
<li class="chapter" data-level="9.4" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with Gio</a></li>
<li class="chapter" data-level="9.5" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-r"><i class="fa fa-check"></i><b>9.5</b> R code</a></li>
<li class="chapter" data-level="9.6" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-js"><i class="fa fa-check"></i><b>9.6</b> JavaScript Code</a><ul>
<li class="chapter" data-level="9.6.1" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-send-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send Selected Keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-set-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set Selected Keys</a></li>
</ul></li>
<li class="chapter" data-level="9.7" data-path="linking-widgets.html"><a href="linking-widgets.html#linking-widgets-using"><i class="fa fa-check"></i><b>9.7</b> Using Crosstalk with Gio</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="widgets-final.html"><a href="widgets-final.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a><ul>
<li class="chapter" data-level="10.1" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-data"><i class="fa fa-check"></i><b>10.1</b> Htmlwidgets and Data</a></li>
<li class="chapter" data-level="10.2" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of Options</a></li>
<li class="chapter" data-level="10.3" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-interface"><i class="fa fa-check"></i><b>10.3</b> Interface Design</a></li>
<li class="chapter" data-level="10.4" data-path="widgets-final.html"><a href="widgets-final.html#widgets-final-exercises"><i class="fa fa-check"></i><b>10.4</b> Exercises</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="11" data-path="shiny-intro.html"><a href="shiny-intro.html"><i class="fa fa-check"></i><b>11</b> Bidirectional Communication</a><ul>
<li class="chapter" data-level="11.1" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-websocket"><i class="fa fa-check"></i><b>11.1</b> WebSocket an Shiny</a></li>
<li class="chapter" data-level="11.2" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-sessions"><i class="fa fa-check"></i><b>11.2</b> Sessions</a></li>
<li class="chapter" data-level="11.3" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-example"><i class="fa fa-check"></i><b>11.3</b> Alerts, an example</a><ul>
<li class="chapter" data-level="11.3.1" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-explore"><i class="fa fa-check"></i><b>11.3.1</b> Explore</a></li>
<li class="chapter" data-level="11.3.2" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-r-to-js"><i class="fa fa-check"></i><b>11.3.2</b> From R to JavaScript</a></li>
<li class="chapter" data-level="11.3.3" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-serialise"><i class="fa fa-check"></i><b>11.3.3</b> Serialisation</a></li>
<li class="chapter" data-level="11.3.4" data-path="shiny-intro.html"><a href="shiny-intro.html#shiny-intro-js2r"><i class="fa fa-check"></i><b>11.3.4</b> JavaScript to R</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="12" data-path="shiny-complete.html"><a href="shiny-complete.html"><i class="fa fa-check"></i><b>12</b> A Complete Integration</a><ul>
<li class="chapter" data-level="12.1" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-discover"><i class="fa fa-check"></i><b>12.1</b> Discover</a></li>
<li class="chapter" data-level="12.2" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-setup"><i class="fa fa-check"></i><b>12.2</b> Setup</a></li>
<li class="chapter" data-level="12.3" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-dependencies"><i class="fa fa-check"></i><b>12.3</b> Dependencies</a></li>
<li class="chapter" data-level="12.4" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-images"><i class="fa fa-check"></i><b>12.4</b> Static Files</a></li>
<li class="chapter" data-level="12.5" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-skeleton"><i class="fa fa-check"></i><b>12.5</b> Skeleton</a></li>
<li class="chapter" data-level="12.6" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-r2js"><i class="fa fa-check"></i><b>12.6</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.7" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-js2r"><i class="fa fa-check"></i><b>12.7</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.8" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-input-handler"><i class="fa fa-check"></i><b>12.8</b> Input handler</a></li>
<li class="chapter" data-level="12.9" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg"><i class="fa fa-check"></i><b>12.9</b> As a Package</a><ul>
<li class="chapter" data-level="12.9.1" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-deps"><i class="fa fa-check"></i><b>12.9.1</b> Dependencies</a></li>
<li class="chapter" data-level="12.9.2" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-trigger"><i class="fa fa-check"></i><b>12.9.2</b> Trigger classification</a></li>
<li class="chapter" data-level="12.9.3" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-js-code"><i class="fa fa-check"></i><b>12.9.3</b> JavaScript code</a></li>
<li class="chapter" data-level="12.9.4" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-input-handler"><i class="fa fa-check"></i><b>12.9.4</b> Input handler</a></li>
<li class="chapter" data-level="12.9.5" data-path="shiny-complete.html"><a href="shiny-complete.html#shiny-complete-pkg-test"><i class="fa fa-check"></i><b>12.9.5</b> Test</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="13" data-path="shiny-tips.html"><a href="shiny-tips.html"><i class="fa fa-check"></i><b>13</b> Tips and Tricks</a><ul>
<li class="chapter" data-level="13.1" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-events"><i class="fa fa-check"></i><b>13.1</b> Shiny Events</a></li>
<li class="chapter" data-level="13.2" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-table-btn"><i class="fa fa-check"></i><b>13.2</b> Table Buttons</a></li>
<li class="chapter" data-level="13.3" data-path="shiny-tips.html"><a href="shiny-tips.html#shiny-tips-jQuery"><i class="fa fa-check"></i><b>13.3</b> jQuery</a></li>
</ul></li>
<li class="chapter" data-level="14" data-path="shiny-output.html"><a href="shiny-output.html"><i class="fa fa-check"></i><b>14</b> Custom Outputs</a><ul>
<li class="chapter" data-level="14.1" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-inner-workings"><i class="fa fa-check"></i><b>14.1</b> Inner-workings</a></li>
<li class="chapter" data-level="14.2" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-setup"><i class="fa fa-check"></i><b>14.2</b> Setup</a></li>
<li class="chapter" data-level="14.3" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-r-fun"><i class="fa fa-check"></i><b>14.3</b> Output R Function</a></li>
<li class="chapter" data-level="14.4" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-html"><i class="fa fa-check"></i><b>14.4</b> Generate Output HTML</a></li>
<li class="chapter" data-level="14.5" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-renderer"><i class="fa fa-check"></i><b>14.5</b> Output Renderer</a></li>
<li class="chapter" data-level="14.6" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-binding"><i class="fa fa-check"></i><b>14.6</b> JavaScript Output Binding</a><ul>
<li class="chapter" data-level="14.6.1" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-title"><i class="fa fa-check"></i><b>14.6.1</b> Boxxy Title</a></li>
<li class="chapter" data-level="14.6.2" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-value"><i class="fa fa-check"></i><b>14.6.2</b> Boxxy Value</a></li>
<li class="chapter" data-level="14.6.3" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-boxxy-bg-color"><i class="fa fa-check"></i><b>14.6.3</b> Boxxy Background Color</a></li>
<li class="chapter" data-level="14.6.4" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-register"><i class="fa fa-check"></i><b>14.6.4</b> Register the Output Binding</a></li>
</ul></li>
<li class="chapter" data-level="14.7" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-usage"><i class="fa fa-check"></i><b>14.7</b> Boxxy Usage</a></li>
<li class="chapter" data-level="14.8" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-inject"><i class="fa fa-check"></i><b>14.8</b> Injecting Dependencies</a></li>
<li class="chapter" data-level="14.9" data-path="shiny-output.html"><a href="shiny-output.html#shiny-output-preprocess"><i class="fa fa-check"></i><b>14.9</b> Preprocessing Custom Outputs</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="shiny-input.html"><a href="shiny-input.html"><i class="fa fa-check"></i><b>15</b> Custom Inputs</a><ul>
<li class="chapter" data-level="15.1" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-setup"><i class="fa fa-check"></i><b>15.1</b> Setup</a></li>
<li class="chapter" data-level="15.2" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-intro"><i class="fa fa-check"></i><b>15.2</b> Switch Input HTML and Style</a></li>
<li class="chapter" data-level="15.3" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-html"><i class="fa fa-check"></i><b>15.3</b> Generate Input HTML</a></li>
<li class="chapter" data-level="15.4" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-binding"><i class="fa fa-check"></i><b>15.4</b> JavaScript Input Binding</a><ul>
<li class="chapter" data-level="15.4.1" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-find"><i class="fa fa-check"></i><b>15.4.1</b> Find Inputs</a></li>
<li class="chapter" data-level="15.4.2" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-get-id"><i class="fa fa-check"></i><b>15.4.2</b> Get Input Id</a></li>
<li class="chapter" data-level="15.4.3" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-get-value"><i class="fa fa-check"></i><b>15.4.3</b> Get Input Value</a></li>
<li class="chapter" data-level="15.4.4" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-set-value"><i class="fa fa-check"></i><b>15.4.4</b> Set Input Value</a></li>
<li class="chapter" data-level="15.4.5" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-receive-msg"><i class="fa fa-check"></i><b>15.4.5</b> Receive Input Messages</a></li>
<li class="chapter" data-level="15.4.6" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-sub-unsub"><i class="fa fa-check"></i><b>15.4.6</b> Subscribe and Unsubscribe Inputs</a></li>
<li class="chapter" data-level="15.4.7" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-rate-policy"><i class="fa fa-check"></i><b>15.4.7</b> Input Rate Policy</a></li>
<li class="chapter" data-level="15.4.8" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-register"><i class="fa fa-check"></i><b>15.4.8</b> Registering the Input Binding</a></li>
</ul></li>
<li class="chapter" data-level="15.5" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-update"><i class="fa fa-check"></i><b>15.5</b> Update Input</a></li>
<li class="chapter" data-level="15.6" data-path="shiny-input.html"><a href="shiny-input.html#shiny-input-excercise"><i class="fa fa-check"></i><b>15.6</b> Exercise</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="shiny-cookies.html"><a href="shiny-cookies.html"><i class="fa fa-check"></i><b>16</b> Cookies</a><ul>
<li class="chapter" data-level="16.1" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-discover"><i class="fa fa-check"></i><b>16.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="16.2" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-setup"><i class="fa fa-check"></i><b>16.2</b> Setup Project</a></li>
<li class="chapter" data-level="16.3" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-javascript"><i class="fa fa-check"></i><b>16.3</b> JavaScript Cookies</a></li>
<li class="chapter" data-level="16.4" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-r-code"><i class="fa fa-check"></i><b>16.4</b> R Code</a></li>
<li class="chapter" data-level="16.5" data-path="shiny-cookies.html"><a href="shiny-cookies.html#shiny-cookies-exercises"><i class="fa fa-check"></i><b>16.5</b> Exercises</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="shiny-widgets.html"><a href="shiny-widgets.html"><i class="fa fa-check"></i><b>17</b> Widgets with Shiny</a><ul>
<li class="chapter" data-level="17.1" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-to-r"><i class="fa fa-check"></i><b>17.1</b> Widgets to R</a></li>
<li class="chapter" data-level="17.2" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-handlers"><i class="fa fa-check"></i><b>17.2</b> Input Handlers for Widgets</a></li>
<li class="chapter" data-level="17.3" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-r-to-widgets"><i class="fa fa-check"></i><b>17.3</b> R to Widgets</a><ul>
<li class="chapter" data-level="17.3.1" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-send-data"><i class="fa fa-check"></i><b>17.3.1</b> Send Data from Widgets</a></li>
<li class="chapter" data-level="17.3.2" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-retrieve"><i class="fa fa-check"></i><b>17.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="17.3.3" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-handle-data"><i class="fa fa-check"></i><b>17.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="17.4" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-proxy"><i class="fa fa-check"></i><b>17.4</b> Proxy Function</a></li>
<li class="chapter" data-level="17.5" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-clear-data"><i class="fa fa-check"></i><b>17.5</b> Clear Data</a></li>
<li class="chapter" data-level="17.6" data-path="shiny-widgets.html"><a href="shiny-widgets.html#shiny-widgets-update"><i class="fa fa-check"></i><b>17.6</b> Update the Widget</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="18" data-path="v8.html"><a href="v8.html"><i class="fa fa-check"></i><b>18</b> The V8 Engine</a><ul>
<li class="chapter" data-level="18.1" data-path="v8.html"><a href="v8.html#v8-installation"><i class="fa fa-check"></i><b>18.1</b> Installation</a></li>
<li class="chapter" data-level="18.2" data-path="v8.html"><a href="v8.html#v8-basics"><i class="fa fa-check"></i><b>18.2</b> Basics</a></li>
<li class="chapter" data-level="18.3" data-path="v8.html"><a href="v8.html#v8-external"><i class="fa fa-check"></i><b>18.3</b> External Libraries</a></li>
<li class="chapter" data-level="18.4" data-path="v8.html"><a href="v8.html#v8-npm"><i class="fa fa-check"></i><b>18.4</b> NPM Packages</a></li>
<li class="chapter" data-level="18.5" data-path="v8.html"><a href="v8.html#v8-pkg"><i class="fa fa-check"></i><b>18.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="19" data-path="v8-ml.html"><a href="v8-ml.html"><i class="fa fa-check"></i><b>19</b> Machine Learning</a><ul>
<li class="chapter" data-level="19.1" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-dependency"><i class="fa fa-check"></i><b>19.1</b> Dependency</a></li>
<li class="chapter" data-level="19.2" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-regression"><i class="fa fa-check"></i><b>19.2</b> Simple Regression</a></li>
<li class="chapter" data-level="19.3" data-path="v8-ml.html"><a href="v8-ml.html#v8-ml-exercises"><i class="fa fa-check"></i><b>19.3</b> Exercises</a></li>
</ul></li>
<li class="part"><span><b>V Robust JavaScript</b></span></li>
<li class="chapter" data-level="20" data-path="webpack-intro.html"><a href="webpack-intro.html"><i class="fa fa-check"></i><b>20</b> Managing JavaScript</a><ul>
<li class="chapter" data-level="20.1" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-example"><i class="fa fa-check"></i><b>20.1</b> Example</a></li>
<li class="chapter" data-level="20.2" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-browser"><i class="fa fa-check"></i><b>20.2</b> Transpiling</a></li>
<li class="chapter" data-level="20.3" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-minification"><i class="fa fa-check"></i><b>20.3</b> Minification</a></li>
<li class="chapter" data-level="20.4" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-structure"><i class="fa fa-check"></i><b>20.4</b> Bundling and Modules</a></li>
<li class="chapter" data-level="20.5" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-decouple"><i class="fa fa-check"></i><b>20.5</b> Decoupling</a></li>
<li class="chapter" data-level="20.6" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-npm"><i class="fa fa-check"></i><b>20.6</b> NPM</a></li>
<li class="chapter" data-level="20.7" data-path="webpack-intro.html"><a href="webpack-intro.html#webpack-conclude"><i class="fa fa-check"></i><b>20.7</b> With R</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html"><i class="fa fa-check"></i><b>21</b> Discover Webpack and NPM</a><ul>
<li class="chapter" data-level="21.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install"><i class="fa fa-check"></i><b>21.1</b> Installation</a><ul>
<li class="chapter" data-level="21.1.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-mac"><i class="fa fa-check"></i><b>21.1.1</b> Mac OS</a></li>
<li class="chapter" data-level="21.1.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-ubuntu"><i class="fa fa-check"></i><b>21.1.2</b> Ubuntu</a></li>
<li class="chapter" data-level="21.1.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-windows"><i class="fa fa-check"></i><b>21.1.3</b> Windows</a></li>
<li class="chapter" data-level="21.1.4" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-other"><i class="fa fa-check"></i><b>21.1.4</b> Other</a></li>
</ul></li>
<li class="chapter" data-level="21.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-setup"><i class="fa fa-check"></i><b>21.2</b> Set Up the App</a></li>
<li class="chapter" data-level="21.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-init-npm"><i class="fa fa-check"></i><b>21.3</b> Initialise NPM</a></li>
<li class="chapter" data-level="21.4" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-install-pkgs"><i class="fa fa-check"></i><b>21.4</b> Installing NPM Packages</a></li>
<li class="chapter" data-level="21.5" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-entry-points"><i class="fa fa-check"></i><b>21.5</b> Entry Point and Output</a></li>
<li class="chapter" data-level="21.6" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-conf"><i class="fa fa-check"></i><b>21.6</b> Configuration File</a></li>
<li class="chapter" data-level="21.7" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-npm-scripts"><i class="fa fa-check"></i><b>21.7</b> NPM scripts</a></li>
<li class="chapter" data-level="21.8" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-webpack-mode"><i class="fa fa-check"></i><b>21.8</b> Source maps</a></li>
<li class="chapter" data-level="21.9" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-bundle"><i class="fa fa-check"></i><b>21.9</b> Bundle</a></li>
<li class="chapter" data-level="21.10" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-internal-dependencies"><i class="fa fa-check"></i><b>21.10</b> Internal Dependencies</a></li>
<li class="chapter" data-level="21.11" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-external-dependencies"><i class="fa fa-check"></i><b>21.11</b> External Dependencies</a></li>
<li class="chapter" data-level="21.12" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export"><i class="fa fa-check"></i><b>21.12</b> Import and Export</a><ul>
<li class="chapter" data-level="21.12.1" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-named"><i class="fa fa-check"></i><b>21.12.1</b> Named</a></li>
<li class="chapter" data-level="21.12.2" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-default"><i class="fa fa-check"></i><b>21.12.2</b> Default</a></li>
<li class="chapter" data-level="21.12.3" data-path="webpack-intro-discover.html"><a href="webpack-intro-discover.html#webpack-intro-import-export-wrap-up"><i class="fa fa-check"></i><b>21.12.3</b> Wrap-up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="22" data-path="packer-overview.html"><a href="packer-overview.html"><i class="fa fa-check"></i><b>22</b> Webpack with R</a><ul>
<li class="chapter" data-level="22.1" data-path="packer-overview.html"><a href="packer-overview.html#packer-principles"><i class="fa fa-check"></i><b>22.1</b> Principles of packer</a></li>
<li class="chapter" data-level="22.2" data-path="packer-overview.html"><a href="packer-overview.html#packer-scaffolds"><i class="fa fa-check"></i><b>22.2</b> Scaffolds</a></li>
<li class="chapter" data-level="22.3" data-path="packer-overview.html"><a href="packer-overview.html#packer-inputs"><i class="fa fa-check"></i><b>22.3</b> Inputs</a></li>
<li class="chapter" data-level="22.4" data-path="packer-overview.html"><a href="packer-overview.html#packer-r-file"><i class="fa fa-check"></i><b>22.4</b> R file</a></li>
<li class="chapter" data-level="22.5" data-path="packer-overview.html"><a href="packer-overview.html#packer-js-files"><i class="fa fa-check"></i><b>22.5</b> JavaScript Files</a></li>
<li class="chapter" data-level="22.6" data-path="packer-overview.html"><a href="packer-overview.html#packer-bundle"><i class="fa fa-check"></i><b>22.6</b> Bundle</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="packer-adv.html"><a href="packer-adv.html"><i class="fa fa-check"></i><b>23</b> Webpack Advanced</a><ul>
<li class="chapter" data-level="23.1" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-widgets"><i class="fa fa-check"></i><b>23.1</b> Widgets</a></li>
<li class="chapter" data-level="23.2" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue"><i class="fa fa-check"></i><b>23.2</b> Shiny with Vue and Bootstrap 4</a><ul>
<li class="chapter" data-level="23.2.1" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-setup"><i class="fa fa-check"></i><b>23.2.1</b> Setup</a></li>
<li class="chapter" data-level="23.2.2" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-bs4"><i class="fa fa-check"></i><b>23.2.2</b> Bootstrap 4 Installation</a></li>
<li class="chapter" data-level="23.2.3" data-path="packer-adv.html"><a href="packer-adv.html#packer-adv-shiny-vue-code"><i class="fa fa-check"></i><b>23.2.3</b> Vue Code</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a><ul>
<li class="chapter" data-level="24.1" data-path="conclusion.html"><a href="conclusion.html#conclusion-performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#conclusion-trial-and-error"><i class="fa fa-check"></i><b>24.2</b> Trial and Error</a></li>
<li class="chapter" data-level="24.3" data-path="conclusion.html"><a href="conclusion.html#conclusion-ux"><i class="fa fa-check"></i><b>24.3</b> Functionality and UX</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="packer-adv" class="section level1">
<h1><span class="header-section-number">Chapter 23</span> Webpack Advanced</h1>
<p>We’re about to cover slightly more advanced uses of NPM and webpack with R using packer. These involve using an NPM dependency to develop a widget and use <a href="https://vuejs.org/">Vue.js</a> and Bootstrap 4 to power the front end of a Shiny application.</p>
<p>Those will make for more concrete cases to bring webpack into your workflow, and also enable explaining more advanced topics only thus far briefly touched upon, such as transpiling.</p>
<div id="packer-adv-widgets" class="section level2">
<h2><span class="header-section-number">23.1</span> Widgets</h2>
<p>The widget scaffold, like all other scaffolds, must be run from within the root of a package. To demonstrate we’ll write a widget for the <a href="https://github.com/inorganik/countUp.js/">countup</a> library that allows animating numbers.</p>
<p>First, we create a package which we name <code>counter</code>. You can name the package differently but avoid naming it <code>countup</code>. We will later have to install the external dependency also named <code>countup</code> and NPM does not allow a project named X to use a dependency also named X.</p>
<div class="sourceCode" id="cb433"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb433-1" title="1">usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;counter&quot;</span>)</a></code></pre></div>
<p>From the root of the package, we scaffold the widget with <code>scaffold_widget</code>, which prints out some information on what packer exactly does.</p>
<div class="sourceCode" id="cb434"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb434-1" title="1">packer<span class="op">::</span><span class="kw">scaffold_widget</span>(<span class="st">&quot;countup&quot;</span>)</a></code></pre></div>
<pre><code>── Scaffolding widget ──────────────────────────────── countup ── 
✔ Bare widget setup
✔ Created srcjs directory
✔ Initialiased npm
✔ webpack, webpack-cli, webpack-merge installed with scope dev
✔ Created srcjs/config directory
✔ Created webpack config files
✔ Created srcjs/modules directory
✔ Created srcjs/widgets directory
✔ Created srcjs/index.js
✔ Moved bare widget to srcjs
✔ Added npm scripts

── Adding files to &#39;.gitignore&#39; and &#39;.Rbuildignore&#39; ──

✔ Setting active project to &#39;/Projects/countup&#39;
✔ Adding &#39;^srcjs$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^node_modules$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^package\\.json$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^package-lock\\.json$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^webpack\\.dev\\.js$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^webpack\\.prod\\.js$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^webpack\\.common\\.js$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;node_modules&#39; to &#39;.gitignore&#39;

── Adding packages to Imports ──

✔ Adding &#39;htmlwidgets&#39; to Imports field in DESCRIPTION
● Refer to functions with `htmlwidgets::fun()`

── Scaffold built ──

ℹ Run `bundle` to build the JavaScript files</code></pre>
<p>Importantly, it runs <code>htmlwidgets::scaffoldWidget</code> internally, there is thus no need to run this function. About the widget itself, there is very little difference between what <code>htmlwidgets::scaffoldWidget</code> and <code>packer::scaffold_widget</code>. While, if you remember, the initial scaffold of htmlwidgets includes a simple function to display a message in HTML using <code>innerText</code>. The scaffold produced by packer differs only in that this message is displayed in <code>&lt;h1&gt;</code> HTML tags. That is so it can, from the get-go, demonstrate how to modularise a widget. We’ll cover that in just a minute, before we do so, bundle the JavaScript and run the <code>counter</code> function to observe the output it generates.</p>
<div class="sourceCode" id="cb436"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb436-1" title="1">packer<span class="op">::</span><span class="kw">bundle</span>()</a>
<a class="sourceLine" id="cb436-2" title="2">devtools<span class="op">::</span><span class="kw">load_all</span>()</a>
<a class="sourceLine" id="cb436-3" title="3"><span class="kw">countup</span>(<span class="st">&quot;Hello widgets!&quot;</span>)</a></code></pre></div>
<p>This indeed displays the message in <code>&lt;h1&gt;</code> HTML tags, now onto unpacking the structure generated by packer. We’ll skip the R code to keep this concise as nothing differs from a standard widget on that side. Instead, we’ll focus on the JavaScript code in the <code>srcjs</code> directory. First, in the <code>srcjs/widgets</code> directory, one will find the file <code>countup.js</code>. This file contains the code that produces the widget.</p>
<p>At the top of the file are the imports. First, it imports <code>widgets</code>, which is the htmlwidgets <em>external dependency,</em> second it imports the function <code>asHeader</code> from the <code>header.js</code> file in the <code>modules</code> directory.</p>
<div class="sourceCode" id="cb437"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb437-1" title="1"><span class="im">import</span> <span class="st">&#39;widgets&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb437-2" title="2"><span class="im">import</span> <span class="op">{</span> asHeader <span class="op">}</span> <span class="im">from</span> <span class="st">&#39;../modules/header.js&#39;</span><span class="op">;</span> </a>
<a class="sourceLine" id="cb437-3" title="3"></a>
<a class="sourceLine" id="cb437-4" title="4"><span class="va">HTMLWidgets</span>.<span class="at">widget</span>(<span class="op">{</span></a>
<a class="sourceLine" id="cb437-5" title="5"></a>
<a class="sourceLine" id="cb437-6" title="6">  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;countup&#39;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb437-7" title="7"></a>
<a class="sourceLine" id="cb437-8" title="8">  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb437-9" title="9"></a>
<a class="sourceLine" id="cb437-10" title="10">  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) <span class="op">{</span></a>
<a class="sourceLine" id="cb437-11" title="11"></a>
<a class="sourceLine" id="cb437-12" title="12">    <span class="co">// </span><span class="al">TODO</span><span class="co">: define shared variables for this instance</span></a>
<a class="sourceLine" id="cb437-13" title="13"></a>
<a class="sourceLine" id="cb437-14" title="14">    <span class="cf">return</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb437-15" title="15"></a>
<a class="sourceLine" id="cb437-16" title="16">      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></a>
<a class="sourceLine" id="cb437-17" title="17"></a>
<a class="sourceLine" id="cb437-18" title="18">        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to render the widget, e.g.</span></a>
<a class="sourceLine" id="cb437-19" title="19">        <span class="va">el</span>.<span class="at">innerHTML</span> <span class="op">=</span> <span class="at">asHeader</span>(x)<span class="op">;</span></a>
<a class="sourceLine" id="cb437-20" title="20"></a>
<a class="sourceLine" id="cb437-21" title="21">      <span class="op">},</span></a>
<a class="sourceLine" id="cb437-22" title="22"></a>
<a class="sourceLine" id="cb437-23" title="23">      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) <span class="op">{</span></a>
<a class="sourceLine" id="cb437-24" title="24"></a>
<a class="sourceLine" id="cb437-25" title="25">        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to re-render the widget with a new size</span></a>
<a class="sourceLine" id="cb437-26" title="26"></a>
<a class="sourceLine" id="cb437-27" title="27">      <span class="op">}</span></a>
<a class="sourceLine" id="cb437-28" title="28"></a>
<a class="sourceLine" id="cb437-29" title="29">    <span class="op">};</span></a>
<a class="sourceLine" id="cb437-30" title="30">  <span class="op">}</span></a>
<a class="sourceLine" id="cb437-31" title="31"><span class="op">}</span>)<span class="op">;</span></a></code></pre></div>
<p>The <code>header.js</code> file includes the <code>asHeader</code> function, which accepts an <code>x</code> argument that is used to create the <code>&lt;h1&gt;</code> message. This function is exported.</p>
<div class="sourceCode" id="cb438"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb438-1" title="1"><span class="kw">const</span> asHeader <span class="op">=</span> (x) <span class="kw">=&gt;</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb438-2" title="2">  <span class="cf">return</span> <span class="st">&#39;&lt;h1&gt;&#39;</span> <span class="op">+</span> <span class="va">x</span>.<span class="at">message</span> <span class="op">+</span> <span class="st">&#39;&lt;/h1&gt;&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb438-3" title="3"><span class="op">}</span></a>
<a class="sourceLine" id="cb438-4" title="4"></a>
<a class="sourceLine" id="cb438-5" title="5"><span class="im">export</span> <span class="op">{</span> asHeader <span class="op">};</span></a></code></pre></div>
<p>We will make changes to the JavaScript so that instead of displaying the message as text, it uses the aforementioned countup library to animate a number. The first order of business is to install countup. Here we use packer to do so; the function call below is identical to running <code>npm install countup --save</code> from the terminal.</p>
<div class="sourceCode" id="cb439"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb439-1" title="1">packer<span class="op">::</span><span class="kw">npm_install</span>(<span class="st">&quot;countup&quot;</span>, <span class="dt">scope =</span> <span class="st">&quot;prod&quot;</span>) </a></code></pre></div>
<p>We will not need the <code>header.js</code> file. We can delete it and in its stead create another file called <code>count.js</code>. This file will include a function that uses countup to animate the numbers. It should accept 1) the id of the element where countup should be used, and 2) the value that countup should animate. This function called <code>counter</code> is, at the end of the file, exported.</p>
<div class="sourceCode" id="cb440"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb440-1" title="1"><span class="im">import</span> <span class="op">{</span> CountUp <span class="op">}</span> <span class="im">from</span> <span class="st">&#39;countup.js&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb440-2" title="2"></a>
<a class="sourceLine" id="cb440-3" title="3"><span class="kw">function</span> <span class="at">counter</span>(id<span class="op">,</span> value)<span class="op">{</span></a>
<a class="sourceLine" id="cb440-4" title="4">  <span class="kw">var</span> countUp <span class="op">=</span> <span class="kw">new</span> <span class="at">CountUp</span>(id<span class="op">,</span> value)<span class="op">;</span></a>
<a class="sourceLine" id="cb440-5" title="5">  <span class="va">countUp</span>.<span class="at">start</span>()<span class="op">;</span></a>
<a class="sourceLine" id="cb440-6" title="6"><span class="op">}</span></a>
<a class="sourceLine" id="cb440-7" title="7"></a>
<a class="sourceLine" id="cb440-8" title="8"><span class="im">export</span> <span class="op">{</span> counter <span class="op">};</span></a></code></pre></div>
<p>We need to add the import statement to bring in the <code>counter</code> function and run it in the <code>renderValue</code> method. Packer also added the htmlwidgets external dependency, which is imported below with <code>import 'widgets'</code>.</p>
<p>Because we left the <em>R function</em> <code>countup</code> untouched, we have to use the default <code>message</code> variable it accepts. Ideally, this argument in the R function should be renamed to something more adequate.</p>
<div class="sourceCode" id="cb441"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb441-1" title="1"><span class="im">import</span> <span class="st">&#39;widgets&#39;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb441-2" title="2"><span class="im">import</span> <span class="op">{</span> counter <span class="op">}</span> <span class="im">from</span> <span class="st">&#39;../modules/count.js&#39;</span><span class="op">;</span> </a>
<a class="sourceLine" id="cb441-3" title="3"></a>
<a class="sourceLine" id="cb441-4" title="4"><span class="va">HTMLWidgets</span>.<span class="at">widget</span>(<span class="op">{</span></a>
<a class="sourceLine" id="cb441-5" title="5"></a>
<a class="sourceLine" id="cb441-6" title="6">  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;countup&#39;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb441-7" title="7"></a>
<a class="sourceLine" id="cb441-8" title="8">  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb441-9" title="9"></a>
<a class="sourceLine" id="cb441-10" title="10">  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) <span class="op">{</span></a>
<a class="sourceLine" id="cb441-11" title="11"></a>
<a class="sourceLine" id="cb441-12" title="12">    <span class="co">// </span><span class="al">TODO</span><span class="co">: define shared variables for this instance</span></a>
<a class="sourceLine" id="cb441-13" title="13"></a>
<a class="sourceLine" id="cb441-14" title="14">    <span class="cf">return</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb441-15" title="15"></a>
<a class="sourceLine" id="cb441-16" title="16">      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) <span class="op">{</span></a>
<a class="sourceLine" id="cb441-17" title="17"></a>
<a class="sourceLine" id="cb441-18" title="18">        <span class="at">counter</span>(<span class="va">el</span>.<span class="at">id</span><span class="op">,</span> <span class="va">x</span>.<span class="at">message</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb441-19" title="19"></a>
<a class="sourceLine" id="cb441-20" title="20">      <span class="op">},</span></a>
<a class="sourceLine" id="cb441-21" title="21"></a>
<a class="sourceLine" id="cb441-22" title="22">      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) <span class="op">{</span></a>
<a class="sourceLine" id="cb441-23" title="23"></a>
<a class="sourceLine" id="cb441-24" title="24">        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to re-render the widget with a new size</span></a>
<a class="sourceLine" id="cb441-25" title="25"></a>
<a class="sourceLine" id="cb441-26" title="26">      <span class="op">}</span></a>
<a class="sourceLine" id="cb441-27" title="27"></a>
<a class="sourceLine" id="cb441-28" title="28">    <span class="op">};</span></a>
<a class="sourceLine" id="cb441-29" title="29">  <span class="op">}</span></a>
<a class="sourceLine" id="cb441-30" title="30"><span class="op">}</span>)<span class="op">;</span></a></code></pre></div>
<p>Finally, the JavaScript bundle can be generated with <code>packer::bundle()</code>, install the package or run <code>devtools::load_all()</code>, and test that the widget works!</p>
<div class="sourceCode" id="cb442"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb442-1" title="1"><span class="kw">countup</span>(<span class="dv">12345</span>)</a></code></pre></div>
<p>That hopefully is a compelling example to use NPM and webpack to build widgets. It could even be argued that it is easier to set up; dependencies are much more manageable; nothing has to be manually downloaded; it will be easier to update them in the future, etc.</p>
</div>
<div id="packer-adv-shiny-vue" class="section level2">
<h2><span class="header-section-number">23.2</span> Shiny with Vue and Bootstrap 4</h2>
<p>In this example, we create a Shiny application that uses <a href="https://vuejs.org/">Vue.js</a> and Bootstrap 4 in the front end. As you may know, Shiny ships with Bootstrap version 3, not 4 (the latest at the time of writing this).</p>
<div id="packer-adv-shiny-vue-setup" class="section level3">
<h3><span class="header-section-number">23.2.1</span> Setup</h3>
<p>If you prefer using <a href="https://reactjs.org/">React</a>, know that it is also supported by webpack and packer. Vue is a framework to create user interfaces that, like React, make much of the front end work much more straightforward. It reduces the amount of code one has to write, simplifies business logic, enables reactivity, and much more.</p>
<p>Since packer only allows placing scaffolds in R packages, the way one can build Shiny applications is using the golem package. Golem is an opinionated framework to build applications <em>as R packages.</em> Writing Shiny applications as R packages brings many of the advantages that packages have to Shiny applications: ease of installation, unit testing, dependency management, etc.</p>
<div class="sourceCode" id="cb443"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb443-1" title="1"><span class="kw">install.packages</span>(<span class="st">&quot;golem&quot;</span>)</a></code></pre></div>
<p>After installing golem from CRAN, we can create an application with the <code>golem::create_golem</code> function; it’s very similar to <code>usethis::create_package</code>, only it prepares a package specifically to build Shiny applications.</p>
<div class="sourceCode" id="cb444"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb444-1" title="1">golem<span class="op">::</span><span class="kw">create_golem</span>(<span class="st">&quot;vuer&quot;</span>)</a></code></pre></div>
<p>From within a golem application, one uses a scaffold specifically designed for this with <code>scaffold_golem</code>. Note that this does not mean other scaffolds will not work, custom Shiny inputs and outputs can also be created with <code>scaffold_input</code> and <code>scaffold_output</code>, respectively. The <code>scaffold_golem</code> function takes two core arguments; <code>vue</code> and <code>react</code>. Setting either of these to <code>TRUE</code> will prepare a scaffold specifically designed to support either Vue or React.</p>
<p>The reason these arguments exist is that webpack requires further configuration that can be tricky to set up manually. Moreover, Vue supports (but does not require) <code>.vue</code> files; these can hold HTML, JavaScript, and CSS. One can think of such files as similar to Shiny modules; they encapsulate a part of the logic of the application for easy modularisation.</p>
<p>When the <code>vue</code> argument is set to <code>TRUE</code> in <code>scaffold_golem</code>, the function does follow the usual procedure or initialising NPM, creating the various files, and directories, but in addition configures two loaders and the vue plugin.</p>
<p>Loaders are transformers, they scan files in the <code>srcjs</code> directory and pre-process them. That allows using, for instance, the Babel compiler that will transform the latest version of JavaScript into code that every browser can run. This compiler is very often used, including here, to compile Vue code. Since Vue allows placing CSS in <code>.vue</code> files, another loader is required; one that will look for CSS and bundle it within the JavaScript file.</p>
<p>Plugins are a feature of webpack that allow extending its functionalities; there is one for Vue, which the function will install and configure for you.</p>
<p>Also, when creating a scaffold for <code>vue</code> or <code>react</code>, one can choose whether to rely on the CDN, in which case they are installed as developer dependencies, or install them for production, in which case they are included in the bundle. It defaults to using the CDN; this is often advised as the CDN will serve the required files faster.</p>
<p>The scaffold also sets up webpack with Babel, the transpiler that allows writing the latest JavaScript, and ensures it will run on (almost) any web browser. Hence, we can use ES6 notation in places.</p>
<div class="sourceCode" id="cb445"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb445-1" title="1">packer<span class="op">::</span><span class="kw">scaffold_golem</span>(<span class="dt">vue =</span> <span class="ot">TRUE</span>)</a></code></pre></div>
<pre><code>── Scaffolding golem ──────────────────────────────────────────
✔ Initialiased npm
✔ webpack, webpack-cli, webpack-merge installed with scope dev
✔ Added npm scripts
✔ Created srcjs directory
✔ Created srcjs/config directory
✔ Created webpack config files

── Adding files to &#39;.gitignore&#39; and &#39;.Rbuildignore&#39; ──

✔ Setting active project to &#39;/Projects/vuer&#39;
✔ Adding &#39;^srcjs$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^node_modules$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^package\\.json$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^package-lock\\.json$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^webpack\\.dev\\.js$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^webpack\\.prod\\.js$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;^webpack\\.common\\.js$&#39; to &#39;.Rbuildignore&#39;
✔ Adding &#39;node_modules&#39; to &#39;.gitignore&#39;

── Vue loader, plugin &amp; dependency ──

✔ babel-loader installed with scope dev
✔ Added loader rule for &#39;babel-loader&#39;
✔ @babel/core, @babel/preset-env installed with scope dev
✔ vue installed with scope dev
✔ vue-loader, vue-template-compiler installed with scope dev
✔ Added loader rule for &#39;vue-loader&#39; and &#39;vue-template-compiler&#39;
✔ style-loader, css-loader installed with scope dev
✔ Added loader rule for &#39;style-loader&#39; and &#39;css-loader&#39;
✔ Created R/vue_cdn.R containing `vueCDN()` function
✔ Added alias to srcjs/config/misc.json

── Babel config file ──

✔ Created &#39;.babelrc&#39;
✔ Adding &#39;^\\.babelrc$&#39; to &#39;.Rbuildignore&#39;

── Template files ──

✔ Added srcjs/Home.vue template
! Place the following in your shiny ui:
tagList(
  vueCDN(),
  div(id = &quot;app&quot;),
  tags$script(src = &quot;www/index.js&quot;)
)

── Scaffold built ──

ℹ Run `bundle` to build the JavaScript files</code></pre>
<p>Note the first instruction that was printed in the console; it states a <code>tagList</code> must be placed in the Shiny UI of the application. It imports the Vue dependency via the CDN with <code>vueCDN()</code>, which is a function created by packer, creates a <code>&lt;DIV&gt;</code> with an id attribute of <code>app</code> that will be used as root of the Vue application; where the application generated by Vue will be placed. It also imports the bundled JavaScript (<code>index.js</code>). So let us place that in the Shiny UI, which is in the <code>R/app_ui.R</code> file.</p>
<div class="sourceCode" id="cb447"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb447-1" title="1">app_ui &lt;-<span class="st"> </span><span class="cf">function</span>(request) {</a>
<a class="sourceLine" id="cb447-2" title="2">  <span class="kw">tagList</span>(</a>
<a class="sourceLine" id="cb447-3" title="3">    <span class="kw">golem_add_external_resources</span>(),</a>
<a class="sourceLine" id="cb447-4" title="4">    <span class="kw">fluidPage</span>(</a>
<a class="sourceLine" id="cb447-5" title="5">      <span class="kw">tagList</span>(</a>
<a class="sourceLine" id="cb447-6" title="6">        <span class="kw">vueCDN</span>(),</a>
<a class="sourceLine" id="cb447-7" title="7">        <span class="kw">div</span>(<span class="dt">id =</span> <span class="st">&quot;app&quot;</span>),</a>
<a class="sourceLine" id="cb447-8" title="8">        tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;www/index.js&quot;</span>)</a>
<a class="sourceLine" id="cb447-9" title="9">      )</a>
<a class="sourceLine" id="cb447-10" title="10">    )</a>
<a class="sourceLine" id="cb447-11" title="11">  )</a>
<a class="sourceLine" id="cb447-12" title="12">}</a></code></pre></div>
<p>To ensure all is correct up to this point we can test the application; the JavaScript can be bundled with <code>packer::bundle()</code> then the app tested by running <code>run_app()</code>.</p>
<div class="sourceCode" id="cb448"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb448-1" title="1">packer<span class="op">::</span><span class="kw">bundle</span>()</a>
<a class="sourceLine" id="cb448-2" title="2">devtools<span class="op">::</span><span class="kw">load_all</span>()</a>
<a class="sourceLine" id="cb448-3" title="3"><span class="kw">run_app</span>()</a></code></pre></div>
</div>
<div id="packer-adv-shiny-vue-bs4" class="section level3">
<h3><span class="header-section-number">23.2.2</span> Bootstrap 4 Installation</h3>
<p>Next, we can install Bootstrap 4; we’ll use <a href="https://bootstrap-vue.org/">bootstrap-vue</a> which contains a lot of Bootstrap 4 components for Vue. We won’t be using any CDN here, so we install those dependencies as production.</p>
<div class="sourceCode" id="cb449"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb449-1" title="1">packer<span class="op">::</span><span class="kw">npm_install</span>(<span class="st">&quot;bootstrap-vue&quot;</span>, <span class="st">&quot;bootstrap&quot;</span>, <span class="dt">scope =</span> <span class="st">&quot;prod&quot;</span>)</a></code></pre></div>
<p>This will cause some issues though, as the Shiny application will have two different versions of Bootstrap, the default version 3 and version 4 from the bundle. We need to remove Bootstrap 3.</p>
<div class="sourceCode" id="cb450"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb450-1" title="1">app_ui &lt;-<span class="st"> </span><span class="cf">function</span>(request) {</a>
<a class="sourceLine" id="cb450-2" title="2">  <span class="kw">tagList</span>(</a>
<a class="sourceLine" id="cb450-3" title="3">    <span class="kw">golem_add_external_resources</span>(),</a>
<a class="sourceLine" id="cb450-4" title="4">    <span class="co"># remove default bootstrap 3</span></a>
<a class="sourceLine" id="cb450-5" title="5">    htmltools<span class="op">::</span><span class="kw">suppressDependencies</span>(<span class="st">&quot;bootstrap&quot;</span>),</a>
<a class="sourceLine" id="cb450-6" title="6">    <span class="kw">fluidPage</span>(</a>
<a class="sourceLine" id="cb450-7" title="7">      <span class="kw">tagList</span>(</a>
<a class="sourceLine" id="cb450-8" title="8">        <span class="kw">vueCDN</span>(),</a>
<a class="sourceLine" id="cb450-9" title="9">        <span class="kw">div</span>(<span class="dt">id =</span> <span class="st">&quot;app&quot;</span>),</a>
<a class="sourceLine" id="cb450-10" title="10">        tags<span class="op">$</span><span class="kw">script</span>(<span class="dt">src =</span> <span class="st">&quot;www/index.js&quot;</span>)</a>
<a class="sourceLine" id="cb450-11" title="11">      )</a>
<a class="sourceLine" id="cb450-12" title="12">    )</a>
<a class="sourceLine" id="cb450-13" title="13">  )</a>
<a class="sourceLine" id="cb450-14" title="14">}</a></code></pre></div>
</div>
<div id="packer-adv-shiny-vue-code" class="section level3">
<h3><span class="header-section-number">23.2.3</span> Vue Code</h3>
<p>Let us now explore the contents of <code>srcjs</code> and code a basic functionality. It’s relatively straightforward; it consists of two files. The first, <code>index.js</code>, creates the Vue application and places it in the <code>div(id = "app")</code>. The code for the app itself is in a <code>.vue</code> file, which it imports with <code>import App from "./Home.vue";</code>.</p>
<div class="sourceCode" id="cb451"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb451-1" title="1"><span class="im">import</span> Vue <span class="im">from</span> <span class="st">&quot;vue&quot;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb451-2" title="2"><span class="im">import</span> App <span class="im">from</span> <span class="st">&quot;./Home.vue&quot;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb451-3" title="3"></a>
<a class="sourceLine" id="cb451-4" title="4"><span class="kw">new</span> <span class="at">Vue</span>(<span class="op">{</span></a>
<a class="sourceLine" id="cb451-5" title="5">  <span class="dt">el</span><span class="op">:</span> <span class="st">&quot;#app&quot;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb451-6" title="6">  <span class="dt">template</span><span class="op">:</span> <span class="st">&quot;&lt;App/&gt;&quot;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb451-7" title="7">  <span class="dt">components</span><span class="op">:</span> <span class="op">{</span> App <span class="op">}</span></a>
<a class="sourceLine" id="cb451-8" title="8"><span class="op">}</span>)<span class="op">;</span></a></code></pre></div>
<p>The first order of business is to import the Bootstrap dependencies that were installed and “use” them in the application. We don’t explain this in great detail here as much of it is specific to Vue and is thus outside the scope of this book.</p>
<div class="sourceCode" id="cb452"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb452-1" title="1"><span class="im">import</span> Vue <span class="im">from</span> <span class="st">&quot;vue&quot;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb452-2" title="2"><span class="im">import</span> <span class="op">{</span> BootstrapVue<span class="op">,</span> IconsPlugin <span class="op">}</span> <span class="im">from</span> <span class="st">&#39;bootstrap-vue&#39;</span></a>
<a class="sourceLine" id="cb452-3" title="3"><span class="co">// import dependencies</span></a>
<a class="sourceLine" id="cb452-4" title="4"><span class="im">import</span> <span class="st">&#39;bootstrap/dist/css/bootstrap.css&#39;</span></a>
<a class="sourceLine" id="cb452-5" title="5"><span class="im">import</span> <span class="st">&#39;bootstrap-vue/dist/bootstrap-vue.css&#39;</span></a>
<a class="sourceLine" id="cb452-6" title="6"><span class="im">import</span> App <span class="im">from</span> <span class="st">&quot;./Home.vue&quot;</span><span class="op">;</span></a>
<a class="sourceLine" id="cb452-7" title="7"></a>
<a class="sourceLine" id="cb452-8" title="8"><span class="co">// attach dependencies</span></a>
<a class="sourceLine" id="cb452-9" title="9"><span class="va">Vue</span>.<span class="at">use</span>(BootstrapVue)</a>
<a class="sourceLine" id="cb452-10" title="10"><span class="va">Vue</span>.<span class="at">use</span>(IconsPlugin)</a>
<a class="sourceLine" id="cb452-11" title="11"></a>
<a class="sourceLine" id="cb452-12" title="12"><span class="kw">new</span> <span class="at">Vue</span>(<span class="op">{</span></a>
<a class="sourceLine" id="cb452-13" title="13">  <span class="dt">el</span><span class="op">:</span> <span class="st">&quot;#app&quot;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb452-14" title="14">  <span class="dt">template</span><span class="op">:</span> <span class="st">&quot;&lt;App/&gt;&quot;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb452-15" title="15">  <span class="dt">components</span><span class="op">:</span> <span class="op">{</span> App <span class="op">}</span></a>
<a class="sourceLine" id="cb452-16" title="16"><span class="op">}</span>)<span class="op">;</span></a></code></pre></div>
<p>The <code>Home.vue</code> file is where the meat of the application is placed. By default, packer creates an app that just displays a message.</p>
<div class="sourceCode" id="cb453"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb453-1" title="1"><span class="op">&lt;</span>template<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb453-2" title="2">  <span class="op">&lt;</span>p<span class="op">&gt;{{</span> greeting <span class="op">}}</span> powered by Vue<span class="op">!</span>&lt;/p<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb453-3" title="3">&lt;/template<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb453-4" title="4"></a>
<a class="sourceLine" id="cb453-5" title="5"><span class="op">&lt;</span>script<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb453-6" title="6"><span class="va">module</span>.<span class="at">exports</span> <span class="op">=</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb453-7" title="7">  <span class="dt">data</span><span class="op">:</span> <span class="kw">function</span>() <span class="op">{</span></a>
<a class="sourceLine" id="cb453-8" title="8">    <span class="cf">return</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb453-9" title="9">      <span class="dt">greeting</span><span class="op">:</span> <span class="st">&quot;Shiny&quot;</span></a>
<a class="sourceLine" id="cb453-10" title="10">    <span class="op">};</span></a>
<a class="sourceLine" id="cb453-11" title="11">  <span class="op">}</span></a>
<a class="sourceLine" id="cb453-12" title="12"><span class="op">};</span></a>
<a class="sourceLine" id="cb453-13" title="13">&lt;/script<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb453-14" title="14"></a>
<a class="sourceLine" id="cb453-15" title="15"><span class="op">&lt;</span>style scoped<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb453-16" title="16">p <span class="op">{</span></a>
<a class="sourceLine" id="cb453-17" title="17">  font<span class="op">-</span><span class="dt">size</span><span class="op">:</span> 2em<span class="op">;</span></a>
<a class="sourceLine" id="cb453-18" title="18">  text<span class="op">-</span><span class="dt">align</span><span class="op">:</span> center<span class="op">;</span></a>
<a class="sourceLine" id="cb453-19" title="19"><span class="op">}</span></a>
<a class="sourceLine" id="cb453-20" title="20">&lt;/style<span class="op">&gt;</span></a></code></pre></div>
<p>Below we make changes to the application, so it features a Boostrap 4 text input. After having entered some text and hitting enter the text entered is displayed below and cleared from the input. We also provide a button that sends the input data to the R server.</p>
<div class="sourceCode" id="cb454"><pre class="sourceCode js"><code class="sourceCode javascript"><a class="sourceLine" id="cb454-1" title="1"><span class="op">&lt;</span>template<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-2" title="2">  <span class="op">&lt;</span>div<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-3" title="3">    <span class="op">&lt;</span>b<span class="op">-</span>form<span class="op">-</span>input </a>
<a class="sourceLine" id="cb454-4" title="4">      v<span class="op">-</span>model<span class="op">=</span><span class="st">&quot;inputText&quot;</span> </a>
<a class="sourceLine" id="cb454-5" title="5">      placeholder<span class="op">=</span><span class="st">&quot;Enter your name&quot;</span> </a>
<a class="sourceLine" id="cb454-6" title="6">      @<span class="va">keyup</span>.<span class="at">enter</span><span class="op">=</span><span class="st">&quot;processText&quot;</span><span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-7" title="7">    &lt;/b<span class="op">-</span>form<span class="op">-</span>input<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-8" title="8">    <span class="op">&lt;</span>b<span class="op">-</span>button </a>
<a class="sourceLine" id="cb454-9" title="9">      @click<span class="op">=</span><span class="st">&quot;processText&quot;</span> </a>
<a class="sourceLine" id="cb454-10" title="10">      variant<span class="op">=</span><span class="st">&quot;outline-primary&quot;</span><span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-11" title="11">      Button</a>
<a class="sourceLine" id="cb454-12" title="12">    &lt;/b<span class="op">-</span>button<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-13" title="13">    <span class="op">&lt;</span>h2<span class="op">&gt;</span>Your name is <span class="op">{{</span> text <span class="op">}}</span>&lt;/h2<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-14" title="14">  &lt;/div<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-15" title="15">&lt;/template<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-16" title="16"></a>
<a class="sourceLine" id="cb454-17" title="17"><span class="op">&lt;</span>script<span class="op">&gt;</span></a>
<a class="sourceLine" id="cb454-18" title="18"><span class="va">module</span>.<span class="at">exports</span> <span class="op">=</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb454-19" title="19">  <span class="dt">data</span><span class="op">:</span> <span class="kw">function</span>() <span class="op">{</span></a>
<a class="sourceLine" id="cb454-20" title="20">    <span class="cf">return</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb454-21" title="21">      <span class="dt">text</span><span class="op">:</span> <span class="st">&#39;&#39;</span><span class="op">,</span></a>
<a class="sourceLine" id="cb454-22" title="22">      <span class="dt">inputText</span><span class="op">:</span> <span class="st">&#39;&#39;</span></a>
<a class="sourceLine" id="cb454-23" title="23">    <span class="op">};</span></a>
<a class="sourceLine" id="cb454-24" title="24">  <span class="op">},</span></a>
<a class="sourceLine" id="cb454-25" title="25">  <span class="dt">methods</span><span class="op">:</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb454-26" title="26">    <span class="dt">processText</span><span class="op">:</span> <span class="kw">function</span>()<span class="op">{</span></a>
<a class="sourceLine" id="cb454-27" title="27">      <span class="kw">this</span>.<span class="at">text</span> <span class="op">=</span> <span class="kw">this</span>.<span class="at">inputText</span> <span class="co">// set text var</span></a>
<a class="sourceLine" id="cb454-28" title="28">      <span class="va">Shiny</span>.<span class="at">setInputValue</span>(<span class="st">&#39;text&#39;</span><span class="op">,</span> <span class="kw">this</span>.<span class="at">text</span>)<span class="op">;</span></a>
<a class="sourceLine" id="cb454-29" title="29">      <span class="kw">this</span>.<span class="at">inputText</span> <span class="op">=</span> <span class="st">&#39;&#39;</span> <span class="co">// remove input once entered</span></a>
<a class="sourceLine" id="cb454-30" title="30">    <span class="op">}</span></a>
<a class="sourceLine" id="cb454-31" title="31">  <span class="op">}</span></a>
<a class="sourceLine" id="cb454-32" title="32"><span class="op">};</span></a>
<a class="sourceLine" id="cb454-33" title="33">&lt;/script<span class="op">&gt;</span></a></code></pre></div>
<p>Finally, we can bundle the JavaScript, and run the application to obtain Figure <a href="packer-adv.html#fig:vue-bs4">23.1</a>.</p>
<div class="sourceCode" id="cb455"><pre class="sourceCode r"><code class="sourceCode r"><a class="sourceLine" id="cb455-1" title="1">packer<span class="op">::</span><span class="kw">bundle</span>()</a>
<a class="sourceLine" id="cb455-2" title="2">devtools<span class="op">::</span><span class="kw">load_all</span>()</a>
<a class="sourceLine" id="cb455-3" title="3"><span class="kw">run_app</span>()</a></code></pre></div>
<div class="figure" style="text-align: center"><span id="fig:vue-bs4"></span>
<img src="images/vue-bs4.png" alt="Shiny application with Vue and Bootstrap 4" width="100%" />
<p class="caption">
FIGURE 23.1: Shiny application with Vue and Bootstrap 4
</p>
</div>
<p>Note how little code was written in order to provide these functionalities. It is one of the most powerful features of frameworks like Vue and React. They are not necessary; this could have been coded in vanilla JavaScript, but would admittedly require much more (difficult to read) code.</p>

</div>
</div>
</div>



            </section>

          </div>
        </div>
      </div>
<a href="packer-overview.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="conclusion.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/lunr.js"></script>
<script src="libs/gitbook-2.6.7/js/clipboard.min.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/7-04-webpack-advanced.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
